/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
import { LanguageInput } from 'shiki/core';

// This file has been converted from https://github.com/trond-snekvik/vscode-rst/blob/master/syntaxes/rst.tmLanguage.json
// If you want to provide a fix or improvement, please create a pull request against the original repository.
// Once accepted there, we are happy to receive an update request.
// version: https://github.com/trond-snekvik/vscode-rst/commit/f0fe19ffde6509be52ad9267a57e1b3df665f072
export const restructuredtext: LanguageInput = {
	scopeName: 'source.rst',
	name: 'restructuredtext',
	patterns: [
		{
			include: '#body',
		},
	],
	repository: {
		$self: {},
		$base: {},
		body: {
			patterns: [
				{
					include: '#title',
				},
				{
					include: '#inline-markup',
				},
				{
					include: '#anchor',
				},
				{
					include: '#line-block',
				},
				{
					include: '#replace-include',
				},
				{
					include: '#footnote',
				},
				{
					include: '#substitution',
				},
				{
					include: '#blocks',
				},
				{
					include: '#table',
				},
				{
					include: '#simple-table',
				},
				{
					include: '#options-list',
				},
			],
		},
		title: {
			match: '^(\\*{3,}|#{3,}|\\={3,}|~{3,}|\\+{3,}|-{3,}|`{3,}|\\^{3,}|:{3,}|"{3,}|_{3,}|\'{3,})$',
			name: 'markup.heading',
		},
		'inline-markup': {
			patterns: [
				{
					include: '#escaped',
				},
				{
					include: '#ignore',
				},
				{
					include: '#ref',
				},
				{
					include: '#literal',
				},
				{
					include: '#monospaced',
				},
				{
					include: '#citation',
				},
				{
					include: '#bold',
				},
				{
					include: '#italic',
				},
				{
					include: '#list',
				},
				{
					include: '#macro',
				},
				{
					include: '#reference',
				},
				{
					include: '#footnote-ref',
				},
			],
		},
		ignore: {
			patterns: [
				{
					match: "'[`*]+'",
				},
				{
					match: '<[`*]+>',
				},
				{
					match: '{[`*]+}',
				},
				{
					match: '\\([`*]+\\)',
				},
				{
					match: '\\[[`*]+\\]',
				},
				{
					match: '"[`*]+"',
				},
			],
		},
		table: {
			begin: '^\\s*\\+[=+-]+\\+\\s*$',
			end: '^(?![+|])',
			beginCaptures: {
				'0': {
					name: 'keyword.control.table',
				},
			},
			patterns: [
				{
					match: '[=+|-]',
					name: 'keyword.control.table',
				},
			],
		},
		'simple-table': {
			match: '^[=\\s]+$',
			name: 'keyword.control.table',
		},
		ref: {
			begin: '(:ref:)`',
			end: '`|^\\s*$',
			name: 'entity.name.tag',
			beginCaptures: {
				'1': {
					name: 'keyword.control',
				},
			},
			patterns: [
				{
					match: '<.*?>',
					name: 'markup.underline.link',
				},
			],
		},
		reference: {
			match: '[\\w-]*[a-zA-Z\\d-]__?\\b',
			name: 'entity.name.tag',
		},
		macro: {
			match: '\\|[^\\|]+\\|',
			name: 'entity.name.tag',
		},
		literal: {
			match: '(:\\S+:)(`.*?`\\\\?)',
			captures: {
				'1': {
					name: 'keyword.control',
				},
				'2': {
					name: 'entity.name.tag',
				},
			},
		},
		monospaced: {
			begin: '(?<=[\\s"\'(\\[{<]|^)``[^\\s`]',
			end: '``|^\\s*$',
			name: 'string.interpolated',
		},
		citation: {
			begin: '(?<=[\\s"\'(\\[{<]|^)`[^\\s`]',
			end: '`_{,2}|^\\s*$',
			name: 'entity.name.tag',
			applyEndPatternLast: false,
		},
		bold: {
			begin: '(?<=[\\s"\'(\\[{<]|^)\\*{2}[^\\s*]',
			end: '\\*{2}|^\\s*$',
			name: 'markup.bold',
		},
		italic: {
			begin: '(?<=[\\s"\'(\\[{<]|^)\\*[^\\s*]',
			end: '\\*|^\\s*$',
			name: 'markup.italic',
		},
		escaped: {
			match: '\\\\.',
			name: 'constant.character.escape',
		},
		list: {
			match: '^\\s*(\\d+\\.|\\* -|[a-zA-Z#]\\.|[iIvVxXmMcC]+\\.|\\(\\d+\\)|\\d+\\)|[*+-])\\s+',
			name: 'keyword.control',
		},
		'line-block': {
			match: '^\\|\\s+',
			name: 'keyword.control',
		},
		'raw-html': {
			begin: '^(\\s*)(\\.{2}\\s+raw\\s*::)\\s+(html)\\s*$',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					name: 'keyword.control',
				},
				'3': {
					name: 'variable.parameter.html',
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
				{
					include: 'text.html.derivative',
				},
			],
		},
		anchor: {
			match: '^\\.{2}\\s+(_[^:]+:)\\s*',
			name: 'entity.name.tag.anchor',
		},
		'replace-include': {
			match: '^\\s*(\\.{2})\\s+(\\|[^\\|]+\\|)\\s+(replace::)',
			captures: {
				'1': {
					name: 'keyword.control',
				},
				'2': {
					name: 'entity.name.tag',
				},
				'3': {
					name: 'keyword.control',
				},
			},
		},
		footnote: {
			match: '^\\s*\\.{2}\\s+\\[(?:[\\w\\.-]+|[#*]|#\\w+)\\]\\s+',
			name: 'entity.name.tag',
		},
		'footnote-ref': {
			match: '\\[(?:[\\w\\.-]+|[#*])\\]_',
			name: 'entity.name.tag',
		},
		substitution: {
			match: '^\\.{2}\\s*\\|([^|]+)\\|',
			name: 'entity.name.tag',
		},
		'options-list': {
			match: '^((?:-\\w|--[\\w-]+|/\\w+)(?:,? ?[\\w-]+)*)(?:  |\\t|$)',
			name: 'variable.parameter',
		},
		blocks: {
			patterns: [
				{
					include: '#domains',
				},
				{
					include: '#doctest',
				},
				{
					include: '#code-block-cpp',
				},
				{
					include: '#code-block-py',
				},
				{
					include: '#code-block-console',
				},
				{
					include: '#code-block-javascript',
				},
				{
					include: '#code-block-yaml',
				},
				{
					include: '#code-block-cmake',
				},
				{
					include: '#code-block-kconfig',
				},
				{
					include: '#code-block-ruby',
				},
				{
					include: '#code-block-dts',
				},
				{
					include: '#code-block',
				},
				{
					include: '#doctest-block',
				},
				{
					include: '#raw-html',
				},
				{
					include: '#block',
				},
				{
					include: '#literal-block',
				},
				{
					include: '#block-comment',
				},
			],
		},
		'block-comment': {
			begin: '^(\\s*)\\.{2}',
			while: '^\\1(?=\\s)|^\\s*$',
			name: 'comment.block',
		},
		'literal-block': {
			begin: '^(\\s*)(.*)(::)\\s*$',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					patterns: [
						{
							include: '#inline-markup',
						},
					],
				},
				'3': {
					name: 'keyword.control',
				},
			},
		},
		block: {
			begin: '^(\\s*)(\\.{2}\\s+\\S+::)(.*)',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					name: 'keyword.control',
				},
				'3': {
					name: 'variable',
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
				{
					include: '#body',
				},
			],
		},
		'block-param': {
			patterns: [
				{
					match: '(:param\\s+(.+?):)(?:\\s|$)',
					captures: {
						'1': {
							name: 'keyword.control',
						},
						'2': {
							name: 'variable.parameter',
						},
					},
				},
				{
					match: '(:.+?:)(?:$|\\s+(.*))',
					captures: {
						'1': {
							name: 'keyword.control',
						},
						'2': {
							patterns: [
								{
									match: '\\b(0x[a-fA-F\\d]+|\\d+)\\b',
									name: 'constant.numeric',
								},
								{
									include: '#inline-markup',
								},
							],
						},
					},
				},
			],
		},
		domains: {
			patterns: [
				{
					include: '#domain-cpp',
				},
				{
					include: '#domain-py',
				},
				{
					include: '#domain-auto',
				},
				{
					include: '#domain-js',
				},
			],
		},
		'domain-cpp': {
			begin: '^(\\s*)(\\.{2}\\s+(?:cpp|c):(?:class|struct|function|member|var|type|enum|enum-struct|enum-class|enumerator|union|concept)::)\\s*(?:(@\\w+)|(.*))',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					name: 'keyword.control',
				},
				'3': {
					name: 'entity.name.tag',
				},
				'4': {
					patterns: [
						{
							include: 'source.cpp',
						},
					],
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
				{
					include: '#body',
				},
			],
		},
		'domain-py': {
			begin: '^(\\s*)(\\.{2}\\s+py:(?:module|function|data|exception|class|attribute|property|method|staticmethod|classmethod|decorator|decoratormethod)::)\\s*(.*)',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					name: 'keyword.control',
				},
				'3': {
					patterns: [
						{
							include: 'source.python',
						},
					],
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
				{
					include: '#body',
				},
			],
		},
		'domain-auto': {
			begin: '^(\\s*)(\\.{2}\\s+auto(?:class|module|exception|function|decorator|data|method|attribute|property)::)\\s*(.*)',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					name: 'keyword.control.py',
				},
				'3': {
					patterns: [
						{
							include: 'source.python',
						},
					],
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
				{
					include: '#body',
				},
			],
		},
		'domain-js': {
			begin: '^(\\s*)(\\.{2}\\s+js:\\w+::)\\s*(.*)',
			end: '^(?!\\1[ \\t]|$)',
			beginCaptures: {
				'2': {
					name: 'keyword.control',
				},
				'3': {
					patterns: [
						{
							include: 'source.js',
						},
					],
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
				{
					include: '#body',
				},
			],
		},
		doctest: {
			begin: '^(>>>)\\s*(.*)',
			end: '^\\s*$',
			beginCaptures: {
				'1': {
					name: 'keyword.control',
				},
				'2': {
					patterns: [
						{
							include: 'source.python',
						},
					],
				},
			},
		},
		'code-block-cpp': {
			begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*(c|c\\+\\+|cpp|C|C\\+\\+|CPP|Cpp)\\s*$',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					name: 'keyword.control',
				},
				'4': {
					name: 'variable.parameter.codeblock.cpp',
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
				{
					include: 'source.cpp',
				},
			],
		},
		'code-block-console': {
			begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*(console|shell|bash)\\s*$',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					name: 'keyword.control',
				},
				'4': {
					name: 'variable.parameter.codeblock.console',
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
				{
					include: 'source.shell',
				},
			],
		},
		'code-block-py': {
			begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*(python)\\s*$',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					name: 'keyword.control',
				},
				'4': {
					name: 'variable.parameter.codeblock.py',
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
				{
					include: 'source.python',
				},
			],
		},
		'code-block-javascript': {
			begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*(javascript)\\s*$',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					name: 'keyword.control',
				},
				'4': {
					name: 'variable.parameter.codeblock.js',
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
				{
					include: 'source.js',
				},
			],
		},
		'code-block-yaml': {
			begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*(ya?ml)\\s*$',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					name: 'keyword.control',
				},
				'4': {
					name: 'variable.parameter.codeblock.yaml',
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
				{
					include: 'source.yaml',
				},
			],
		},
		'code-block-cmake': {
			begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*(cmake)\\s*$',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					name: 'keyword.control',
				},
				'4': {
					name: 'variable.parameter.codeblock.cmake',
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
				{
					include: 'source.cmake',
				},
			],
		},
		'code-block-kconfig': {
			begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*([kK]config)\\s*$',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					name: 'keyword.control',
				},
				'4': {
					name: 'variable.parameter.codeblock.kconfig',
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
				{
					include: 'source.kconfig',
				},
			],
		},
		'code-block-ruby': {
			begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*(ruby)\\s*$',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					name: 'keyword.control',
				},
				'4': {
					name: 'variable.parameter.codeblock.ruby',
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
				{
					include: 'source.ruby',
				},
			],
		},
		'code-block-dts': {
			begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*(dts|DTS|devicetree)\\s*$',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					name: 'keyword.control',
				},
				'4': {
					name: 'variable.parameter.codeblock.dts',
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
				{
					include: 'source.dts',
				},
			],
		},
		'code-block': {
			begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					name: 'keyword.control',
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
			],
		},
		'doctest-block': {
			begin: '^(\\s*)(\\.{2}\\s+doctest::)\\s*$',
			while: '^\\1(?=\\s)|^\\s*$',
			beginCaptures: {
				'2': {
					name: 'keyword.control',
				},
			},
			patterns: [
				{
					include: '#block-param',
				},
				{
					include: 'source.python',
				},
			],
		},
	},
};
